package com.lbssoft.gpsbd.controller;

import com.lbssoft.gpsbd.dao.PositionMapper;
import com.lbssoft.gpsbd.model.SocketMsg;
import com.lbssoft.gpsbd.model.User;
import com.lbssoft.gpsbd.model.vo.PositionStatus;
import com.lbssoft.gpsbd.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint(value = "/websocket/{token}")
@Component
public class WebSocket {
	private static ApplicationContext applicationContext;
	
	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	private static int onlineCount = 0;
	private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();

	private Session session;
	
	private int userId;
	

	@OnOpen
	public void onOpen(@PathParam("token") String token, Session session) throws IOException{
		UserService userService = (UserService)applicationContext.getBean(UserService.class);
		User user = userService.getUserByToken(token);
		if(user==null){
			this.onClose();
			return;
		}
		this.session = session;
		this.userId = (int) user.getId();
		webSocketSet.add(this);
		incrOnlineCount();
		userService.updateStatus(1,user.getId());

		logger.info("{}建立链接…当前在线计数: {}",this.userId, getOnlineCount());
		PositionMapper positionMapper = (PositionMapper)applicationContext.getBean(PositionMapper.class);
		Collection<PositionStatus> positionMsgs = new ArrayList<PositionStatus>();
		positionMsgs.addAll(positionMapper.getLastPostionByUid(this.getUserId()));
		SocketMsg socketMsg = new SocketMsg("positions",positionMsgs);
		sendMessage(socketMsg);
	}

	@OnClose
	public void onClose() throws IOException{
		webSocketSet.remove(this);
		decOnlineCount();
		UserService userService = (UserService)applicationContext.getBean(UserService.class);
		userService.updateStatus(0,this.getUserId());
		logger.info("一个连接关闭…当前在线计数: {}", getOnlineCount());

	}

	 /**  
     * 收到客户端消息后调用的方法  
     * @param message 客户端发送过来的消息  
     * @param session 可选的参数  
     */  
	@OnMessage
	public void onMessage(String message, Session session) throws IOException {
		logger.info("收到消息: {}", message);
		this.session = session;
	}

	@OnError
	public void onError(Throwable e, Session session){
		logger.info("{}退出,异常: {}",this.getUserId(),e.toString());
	}


	public void sendMessage(SocketMsg socketMsg) throws IOException {
		this.session.getBasicRemote().sendText(socketMsg.toJSONString());
	}
	
	public static synchronized CopyOnWriteArraySet<WebSocket> clients(){
		return WebSocket.webSocketSet;
	}

	public static synchronized int getOnlineCount(){
		return WebSocket.onlineCount;
	}

	public static synchronized void incrOnlineCount(){
		WebSocket.onlineCount++;
	}

	public static synchronized void decOnlineCount(){
		WebSocket.onlineCount--;
	}

	public int getUserId() {
		return userId;
	}

	public void setUserId(int userId) {
		this.userId = userId;
	}


	public static void setApplicationContext(ApplicationContext context) {
	    applicationContext = context;
	  }
}